package com.example.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.bean.Order;
import com.example.bean.OrderItem;
import com.example.bean.Product;
import com.example.bean.User;
import com.example.order.mapper.OrderItemMapper;
import com.example.order.mapper.OrderMapper;
import com.example.order.service.OrderService;
import com.example.params.OrderParams;
import com.example.shoputils.constants.HttpCode;
import com.example.shoputils.resp.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @Author 刘武贵
 * @Date 2024/2/28 1:09
 * @Description 功能描述：订单接口实现类
 *
 */
@Slf4j
@Service("orderServiceV1")
public class OrderServiceV1Impl implements OrderService {

    /**
     * 订单Mapper
     */
    @Resource
    private OrderMapper orderMapper;

    /**
     * 订单条目Mapper
     */
    @Resource
    private OrderItemMapper orderItemMapper;

    /**
     * RestTemplate对象，用于发送HTTP请求
     */
    @Resource
    private RestTemplate restTemplate;

    /**
     * 保存订单
     * （1）判断orderParams封装的参数是否为空，如果参数为空，则抛出参数异常。
     * （2）通过RestTemplate调用用户微服务获取用户的基本信息，如果获取的用户信息为空，则抛出未获取到用户信息的异常。
     * （3）通过RestTemplate调用商品微服务获取商品的基本信息，如果获取的商品信息为空，则抛出未获取到商品信息的异常。
     * （4）判断商品的库存是否小于待扣减的商品数量，如果商品的库存小于待扣减的商品数量，则抛出商品库存不足的异常。
     * （5）如果orderParams封装的参数不为空，并且获取的用户信息和商品信息不为空，同时商品的库存充足，则创建订单对象保存订单信息，创建订单条目对象，保存订单条目信息。
     * （6）调用商品微服务的接口扣减商品库存。
     * @param orderParams 订单参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(OrderParams orderParams) {
        // 判断订单参数是否为空
        if (orderParams.isEmpty()){
            throw new RuntimeException("参数异常: " + JSONObject.toJSONString(orderParams));
        }

        // 获取用户信息 http://localhost:8060/user/get/ http://server-user:8060/user/get/
        User user = restTemplate.getForObject("http://localhost:8060/user/get/" + orderParams.getUserId(), User.class);
        if (user == null){
            throw new RuntimeException("未获取到用户信息: " + JSONObject.toJSONString(orderParams));
        }
        // 获取商品信息 http://localhost:8070/product/get/ http://server-product:8070/product/get/
        Product product = restTemplate.getForObject("http://localhost:8070/product/get/" + orderParams.getProductId(), Product.class);
        if (product == null){
            throw new RuntimeException("未获取到商品信息: " + JSONObject.toJSONString(orderParams));
        }
        // 判断商品库存是否充足
        if (product.getProStock() < orderParams.getCount()){
            throw new RuntimeException("商品库存不足: " + JSONObject.toJSONString(orderParams));
        }
        // 创建订单对象
        Order order = new Order();
        order.setAddress(user.getAddress());
        order.setPhone(user.getPhone());
        order.setUserId(user.getId());
        order.setUsername(user.getUsername());
        order.setTotalPrice(product.getProPrice().multiply(BigDecimal.valueOf(orderParams.getCount())));
        // 保存订单到数据库
        orderMapper.insert(order);

        // 创建订单项对象
        OrderItem orderItem = new OrderItem();
        orderItem.setNumber(orderParams.getCount());
        orderItem.setOrderId(order.getId());
        orderItem.setProId(product.getId());
        orderItem.setProName(product.getProName());
        orderItem.setProPrice(product.getProPrice());
        // 保存订单项到数据库
        orderItemMapper.insert(orderItem);

        // 更新商品库存
        Result<Integer> result = restTemplate.getForObject("http://localhost:8070/product/update_count/" + orderParams.getProductId() + "/" + orderParams.getCount(), Result.class);
        if (result.getCode() != HttpCode.SUCCESS){
            throw new RuntimeException("库存扣减失败");
        }
        log.info("库存扣减成功");
    }
}